package logger

import (
	"os"
	"path/filepath"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var (
	// Logger 全局logger实例
	Logger *zap.Logger
	// Sugar 提供更简洁API的logger
	Sugar *zap.SugaredLogger
)

// Config 日志配置
type Config struct {
	Level      string // debug, info, warn, error
	Format     string // json, console
	OutputPath string // 输出路径，"" 表示stdout
	ErrorPath  string // 错误日志路径，"" 表示stderr
}

// DefaultConfig 返回默认配置
func DefaultConfig() *Config {
	return &Config{
		Level:      "info",
		Format:     "console",
		OutputPath: "",
		ErrorPath:  "",
	}
}

// Initialize 初始化日志系统
func Initialize(cfg *Config) error {
	if cfg == nil {
		cfg = DefaultConfig()
	}

	// 设置日志级别
	level, err := zapcore.ParseLevel(cfg.Level)
	if err != nil {
		level = zapcore.InfoLevel
	}

	// 创建encoder配置
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "timestamp",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		FunctionKey:    zapcore.OmitKey,
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.CapitalColorLevelEncoder, // 彩色输出
		EncodeTime:     customTimeEncoder,                // 自定义时间格式
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder, // 短路径格式
	}

	// 根据格式选择encoder配置
	if cfg.Format == "json" {
		encoderConfig.EncodeLevel = zapcore.LowercaseLevelEncoder // JSON格式不需要颜色
	}

	// 设置输出路径
	var outputPaths, errorPaths []string

	if cfg.OutputPath == "" {
		outputPaths = []string{"stdout"}
	} else {
		// 确保日志目录存在
		if err := ensureDir(cfg.OutputPath); err != nil {
			return err
		}
		outputPaths = []string{cfg.OutputPath}
	}

	if cfg.ErrorPath == "" {
		errorPaths = []string{"stderr"}
	} else {
		// 确保日志目录存在
		if err := ensureDir(cfg.ErrorPath); err != nil {
			return err
		}
		errorPaths = []string{cfg.ErrorPath}
	}

	// 创建zap配置
	zapConfig := zap.Config{
		Level:       zap.NewAtomicLevelAt(level),
		Development: false,
		Sampling: &zap.SamplingConfig{
			Initial:    100,
			Thereafter: 100,
		},
		Encoding:         cfg.Format,
		EncoderConfig:    encoderConfig,
		OutputPaths:      outputPaths,
		ErrorOutputPaths: errorPaths,
	}

	// 构建logger
	Logger, err = zapConfig.Build(zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
	if err != nil {
		return err
	}

	// 创建SugaredLogger
	Sugar = Logger.Sugar()

	// 设置为全局logger
	zap.ReplaceGlobals(Logger)

	return nil
}

// customTimeEncoder 自定义时间编码器
func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
	enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
}

// ensureDir 确保目录存在
func ensureDir(filePath string) error {
	dir := filepath.Dir(filePath)
	if dir != "." && dir != "/" {
		return os.MkdirAll(dir, 0755)
	}
	return nil
}

// Sync 同步日志缓冲区
func Sync() {
	if Logger != nil {
		_ = Logger.Sync()
	}
}

// Close 关闭日志系统
func Close() {
	Sync()
}

// GetLogger 获取logger实例
func GetLogger() *zap.Logger {
	return Logger
}

// GetSugar 获取SugaredLogger实例
func GetSugar() *zap.SugaredLogger {
	return Sugar
}

// SetLevel 动态设置日志级别
func SetLevel(level string) error {
	if Logger == nil {
		return nil
	}

	_, err := zapcore.ParseLevel(level)
	if err != nil {
		return err
	}

	// 这里需要重新创建logger，因为zap的level是原子的
	// 在生产环境中，建议使用zap.NewAtomicLevel()来动态改变级别
	return Initialize(&Config{
		Level:  level,
		Format: "console", // 默认使用console格式
	})
}

// WithFields 添加字段到logger
func WithFields(fields ...zap.Field) *zap.Logger {
	if Logger == nil {
		return zap.NewNop()
	}
	return Logger.With(fields...)
}

// 便捷方法
func Debug(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Debug(msg, fields...)
	}
}

func Info(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Info(msg, fields...)
	}
}

func Warn(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Warn(msg, fields...)
	}
}

func Error(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Error(msg, fields...)
	}
}

func Fatal(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Fatal(msg, fields...)
	}
}

func Panic(msg string, fields ...zap.Field) {
	if Logger != nil {
		Logger.Panic(msg, fields...)
	}
}

// Sugar便捷方法
func Debugf(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Debugf(template, args...)
	}
}

func Infof(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Infof(template, args...)
	}
}

func Warnf(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Warnf(template, args...)
	}
}

func Errorf(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Errorf(template, args...)
	}
}

func Fatalf(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Fatalf(template, args...)
	}
}

func Panicf(template string, args ...interface{}) {
	if Sugar != nil {
		Sugar.Panicf(template, args...)
	}
}
